查看原文
其他

58安居客二手房 API Gateway Sidecar 实践

董菲 58技术 2022-03-15

导读

58安居客二手房业务线的技术架构合并后,许多老页面需要逐步的重构成同一套技术体系,Web端采用NodeJs渲染,App后端API采用Java,再加上部分老的页面仍然使用的PHP。我们在对外接口这一层有很多通用的拦截功能,例如签名验证、用户票据验签、反爬虫拦截、公共参数处理、城市域名解析等。3套不同的技术栈意味着这些功能都要用不同的语言重复开发3遍,各端逻辑难以统一和维护,面临不少困难,因此亟需一个API网关能够统一的处理这些逻辑,降低维护成本。


背景

58安居客二手房业务线的技术架构合并后,许多老页面需要逐步的重构成同一套技术体系,Web端采用NodeJs渲染,App后端API采用Java,再加上部分老的页面仍然使用的PHP。我们在对外接口这一层有很多通用的拦截功能,例如签名验证、用户票据验签、反爬虫拦截、公共参数处理、城市域名解析等。3套不同的技术栈意味着这些功能都要用不同的语言重复开发3遍,各端逻辑难以统一和维护,面临不少困难,因此亟需一个API网关能够统一的处理这些逻辑,降低维护成本。

API Gateway 选型

考虑到会有很多定制需求,加上二手房技术团队本身对Java比较熟悉,因此直接选择了Java技术栈下的解决方案。主要有3种:
  • 基于Netty定制
  • Spring Cloud Zuul
  • Spring Cloud Gateway
网关作为所有流量的入口,对于吞吐量、稳定性、请求延迟、资源占用都有着更高的要求。Zuul是基于Servlet的同步线程模型,不可避免的容易存在一些IO阻塞的场景导致线程频繁切换、线程阻塞等问题。而纯异步的线程和IO模型,能够减少线程开销、避免IO阻塞,因此在网关上Netty定制和Spring Cloud Gateway都是更好的选择
而Netty定制需要比较多的开发资源投入,二手房技术团队重心还是在业务项目上,没有太大精力完全自研。最终我们选择了底层同样基于Netty的Spring Cloud Gateway
Spring Cloud Gateway是Spring Cloud最新的网关组件,底层基于Project Reactor和Spring Webflux构建。Project Reactor提供了一套响应式编程风格的API以及底层基于Netty的异步网络请求模型,能够提供一套纯异步的编程和运行环境,在高并发的场景下能够比较好的利用CPU资源,避免出问题时大量线程阻塞的问题。


什么是API Gateway Sidecar

传统的网关部署模式下,一般是外网流量进来以后直接进入到网关层,网关处理通用逻辑之后,再将流量转发给后端的业务服务器

但是58的运维架构如果要改成上述这种模式,成本风险都比较大,而且短期内只有房产二手房业务线一个团队有这样的需求。另外对接容器云平台的服务发现功能也比较复杂,短期内可行的架构如下:
但是这种模式很快就被我们否定了,内网流量增加3倍,运维成本和系统稳定性都增加了很多不确定性。因此需要寻找一个既能满足我们的需求,又能适配当前58的运维和容器云平台架构的模式
我们将目光瞄向了Service Mesh架构中的Sidecar模式。Sidecar模式是在容器内部部署了一个Sidecar进程,流量先经过Sidecar代理,完成鉴权、日志、服务注册发现等功能。参考Sidecar模式,我们可以在容器内部署一个API Gateway进程,拦截进来的http流量,进行处理后再转发到原来的web进程。于是我们的部署结构如下:
这样在现有的运维和容器云架构下能够完美的实现我们需要的功能,流量和运维成本都没有太大的增加,我们只需要处理好Sidecar进程的监控即可


容器内Gateway进程部署

公司的云平台提供了启动脚本的钩子和自定义上传文件的功能,我们可以很轻松的实现网关安装包的安装和进程启动。不过Gateway进程的监控和容器关闭的钩子目前没有直接支持,已经和云平台的同学提需求后续考虑支持
Java版本选择了JDK 11,对G1 GC延迟有比较大的优化,能够减少GC对网关的影响。Gateway进程内部本身没有太多的大内存使用,我们也希望资源能够占用尽量少一点,因此JVM堆大小选择了512MB
最后结合云平台提供的镜像商店,我们将这些功能都集成到一起放到一个基础镜像中。这样业务集群需要接入的时候直接继承Gateway的镜像即可。后续镜像的维护升级也可以由Gateway负责的同学统一安排


功能定制,模板化

在最初的版本上我们主要实现了4个功能
  • http跳转https
  • 用户登陆票据验证
  • 城市域名、路径解析
  • 反爬虫服务接入
需要注意的是以上功能都需要同时支持58和安居客两个网站
功能开发上,由于二手房之前积累了不少CompletableFuture的使用经验,因此Reactor的Mono/Flux API上手起来还比较快。用户登陆的票据验证,由于云账号只提供了同步版本的SDK,因此我们暂时使用了线程池来兼容,后续云账号会提供支持异步版本的SDK供我们集成。反爬虫则基于SCF的异步调用来实现。
由于不同域名(58.com/anjuke.com)、不同平台(web/app/小程序)城市解析还有反爬参数都不同,我们提供了模板化的预定义配置文件,业务方在接入时只需要根据当前集群支持的域名,直接引入模板配置即可快速上线


性能压测

我们使用ab对网关进行了压测,测试方式为网关在处理完上述4个功能的逻辑后直接返回200给请求方,流量不经过业务进程。
测试容器为4核4G的云平台容器:
并发数
P99
最慢请求
QPS
4
4

20ms

1500

8
7
30ms
2100
16
1135ms
2200

4并发发的情况下,P99 4ms的性能开销完全满足我们的业务需求。8并发时也有不错的性能,而且4核单机2000 QPS至少能保证网关进程性能是远超过业务的Node/Java/PHP进程的

GC方面,Young GC基本维持在2~5ms,约1300次请求一次Young GC,对性能的影响目前来说没有太大问题。另外我们压测了大约近百万次请求都没有发生Mix GC,Old区的堆大小一直也比较稳定的维持在25%左右。


上线实测

完成上述这些步骤后,我们开始在线上的集群实际的测试。我们先选取了一个流量很小的集群完成线上的初步验证后,开始在二手房业务mobile web最核心的二手房详情页进行应用。这个页面本身是使用NodeJs运行的
实际上线后,由于NodeJs中反爬、获取票据的逻辑都迁移到了Gateway中,整体的页面性能,平均速度提升了20%+,p95性能提升5~10%。
更为重要的是,之前的NodeJs在高峰期或者遭到爬虫突然的大量请求时,响应时间的波动非常大。Gateway上线以后有效的平抑了这部分波动,减轻NodeJS进程的压力。
资源使用方面,CPU占用平均增加约5%,内存占用增加不到1G。
监控方面,由于初期规模较小,目前只是依赖了Spring Boot Admin来进行简单的监控,后续这方面需要投入比较大的精力迭代。


总结及后续优化

目前这套Gateway已经在房产二手房业务线多个NodeJs和Java集群上线,给业务开发同学,特别是前端的同学减轻了不少维护成本。
后续的优化方向上主要是在性能、监控、通用化上进行优化
  1. 性能方面主要是优化日志的打印,进一步降低CPU开销以及GC频率的降低
  2. 监控上未来需要加强Gateway进程可用性的监控,避免假死;以及报警手段的加强
  3. 通用化上,我们希望这个组件能够更加的可定制化和可扩展,方便其他业务线的团队有需求时能够快速的应用上线

作者简介:
董菲:房产事业群--二手房用户技术部 后端架构师

推荐阅读:
营销自动化系统设计与实现
从Mach-O角度谈谈Swift和OC的存储差异
文本预训练模型在信息安全场景的探索和实践

福利环节

 为了鼓励优质内容传播,【58技术】公众号近期会持续推出不定期活动奖励。

  1. 评论区参与话题讨论,#前后端交互的痛点#

  2. 将抽取三个优质评论,送出定制版新年代码台历一本

  3. 活动时间:截至2021年1月24日



您可能也对以下帖子感兴趣

文章有问题?点此查看未经处理的缓存